﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Darkmoon.DX11Imported;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace App1
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            D3D11_CREATE_DEVICE_FLAG creationFlags = D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if DEBUG
            creationFlags |= D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_DEBUG;
#endif
            D3D_FEATURE_LEVEL[] featureLevels = new[]
	        {
		        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_1,
		        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0,
		        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_10_1,
		        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_10_0,
		        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_9_3,
		        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_9_2,
		        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_9_1
	        };
            DX11ImportLib_GlobalMethods.D3D11CreateDevice(null, D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE, IntPtr.Zero, creationFlags, featureLevels, (uint)featureLevels.Length, DX_SDK_VERSIONS.D3D11_SDK_VERSION, out pDevice, out pDC);

            DXGI_SWAP_CHAIN_DESC1 swapChainDesc = new DXGI_SWAP_CHAIN_DESC1();
            swapChainDesc.Width = (uint)Window.Current.Bounds.Width;
            swapChainDesc.Height = (uint)Window.Current.Bounds.Height;
            swapChainDesc.Format = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;           // this is the most common swapchain format
            swapChainDesc.Stereo = 0;
            swapChainDesc.SampleDesc.Count = 1;                          // don't use multi-sampling
            swapChainDesc.SampleDesc.Quality = 0;
            swapChainDesc.BufferUsage = DXGI_USAGE.DXGI_USAGE_RENDER_TARGET_OUTPUT;
            swapChainDesc.BufferCount = 2;
            swapChainDesc.Scaling = DXGI_SCALING.DXGI_SCALING_STRETCH;
            swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // we recommend using this swap effect for all applications
            swapChainDesc.Flags = 0;

            IDXGIDevice dxgiDev = (IDXGIDevice)pDevice;
            IDXGIAdapter adp;
            dxgiDev.GetAdapter(out adp);
            IDXGIFactory2 fac2 = (IDXGIFactory2)adp.GetParent(DX11_Guids_And_Consts.IID_IDXGIFactory2);
            fac2.CreateSwapChainForComposition(pDevice, swapChainDesc, null, out pSwapChain);

            object pBackBufferRaw = null;
            pSwapChain.GetBuffer(0, DX11_Guids_And_Consts.IID_ID3D11Texture2D, out pBackBufferRaw);
            pBackBuffer = (ID3D11Texture2D)pBackBufferRaw;
            pDevice.CreateRenderTargetView(pBackBuffer, out pRTV);
            pDC.OMSetRenderTargets(pRTV);

            D3D11_VIEWPORT vp;
            vp.Width = (float)Window.Current.Bounds.Width;
            vp.Height = (float)Window.Current.Bounds.Height;
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            pDC.RSSetViewports(vp);

            ((ISwapChainBackgroundPanelNative)pan_Swap).SetSwapChain(pSwapChain);

            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(200);
            timer.Tick += (sender, e) =>
            {
                float[] color = new float[] { (float)ran.NextDouble(), (float)ran.NextDouble(), (float)ran.NextDouble(), 1.0f };
                pDC.ClearRenderTargetView(pRTV, color);
                var rv = pSwapChain.Present(0, new DXGI_PRESENT());
            };
            timer.Start();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        ID3D11Texture2D pBackBuffer = null;
        ID3D11Device pDevice = null;
        ID3D11DeviceContext pDC = null;
        IDXGISwapChain pSwapChain = null;
        ID3D11RenderTargetView pRTV = null;
        DispatcherTimer timer = null;
        Random ran = new Random();
    }
}
